// MessageShowArea.h
// Created by Limou on 24-8-17.
//

#ifndef FRONTEND_MESSAGESHOWAREA_HPP
#define FRONTEND_MESSAGESHOWAREA_HPP

#include <QScrollArea>
#include <QWidget>
#include <QScrollBar>
#include <QVBoxLayout>
#include <QLabel>
#include <QPushButton>
#include <QTimer>
#include "../../common/Common.hpp"
#include "../../model/MessageModel.hpp"
#include "../../model/UserModel.hpp"
#include "../TextMessageBubble/TextMessageBubble.hpp"
#include "../SelfInfoWidget/SelfInfoWidget.hpp"
#include "../OtherInfoWidget/OtherInfoWidget.hpp"

// >>> class MessageItem begin: 滚动区域内的气泡子项类 >>>
namespace chat_system::subassembly {
    class MessageItem : public QWidget {
    Q_OBJECT

    private:
        // 部件
        QPushButton* userBtn_; // 头像按钮部件
        QLabel* nameLabel_; // 昵称标签部件
        TextMessageBubble* textMessageBubble_; // 消息气泡部件
        SelfInfoWidget* selfInfoWidget_; // 登录用户卡片
        OtherInfoWidget* otherInfoWidget_; // 其他用户卡片

        // 数据
        bool isLeft_; // 存储消息的靠边状态
        const model::MessageModel messageModel_; // 消息数据

    public:
        // 构造方法
        MessageItem(
            const bool& isLeft,
            const model::MessageModel& messageModel,
            QWidget* parent = nullptr)
                : QWidget(parent)
                , userBtn_(new QPushButton(this))
                , nameLabel_(new QLabel(this))
                , textMessageBubble_(new TextMessageBubble(this))
                , selfInfoWidget_(nullptr)
                , otherInfoWidget_(nullptr)
                , isLeft_(isLeft)
                , messageModel_(messageModel) {
            this->setElement(); // 设置组件
            this->setElementStyle(); // 设置组件样式
            this->setElementLayout(); // 设置组件布局
            this->setElementSignalSlot(messageModel); // 设置信号槽
        }

        // 析构方法
        ~MessageItem() override = default;

    private:
        // 设置组件方法
        void setElement() {
            // TODO: 这里的 messageModel 有点小问题, 应该在用户修改任意一张卡片的时候, 发送给远端, 保存到本地缓存文件, 然后重新绘制左窗口和右窗口
            // TODO: 可以考虑后期使用下面这种方法进行更新组件, 而如果是其他用户更改了自己的信息, 默认只有在下次登录的时候使用网络接口才可以更新, 无论如何用户的 id 是不变的, 如果用户需要在没有更新的时候添加该用户, 就会导致该用户被刷新
            /* void SelfInfoWidget::resetWidget() {
                    //清理当前组件的内容
                    ...

                    // 重新初始化组件
                    this->userIdTag_ = new QLabel(this);
                    this->userIdLab_ = new QLabel(this);
                    // 其他初始化代码...
                }
             */
            // 设置头像按钮部件
            userBtn_->setFixedSize(40, 40);
            userBtn_->setIconSize(QSize(40, 40));
            userBtn_->setIcon(QIcon(messageModel_.getMessageSenderUser().getUserAvatarIco()));

            // 设置昵称标签部件
            nameLabel_->setText(messageModel_.getMessageSenderUser().getUserNickName() + " | " + common::Tools::getInstance()->makeFormatTime(
                    messageModel_.getMessageTime()));
            nameLabel_->setAlignment(Qt::AlignBottom); // 修改文本到标签边框底部的的距离

            QFont font;
            font.setFamily("微软雅黑");
            font.setPixelSize(12);
            nameLabel_->setFont(font);

            // 设置气泡消息部件
            textMessageBubble_->setContent(messageModel_.getMessageContent()); // TODO: 如果是右边, 应该读取本地或远端用户保存的信息
        }

        // 设置组件样式方法
        void setElementStyle() {
            userBtn_->setStyleSheet("QPushButton { border: none;}");
            nameLabel_->setStyleSheet("QLabel { color: rgb(178, 178, 178); font-size: 12px; border: none; }");
            nameLabel_->setStyleSheet("QLabel { color: rgb(178, 178, 178); font-size: 12px; border: none; line-height: 12px; }");
        }

        // 设置组件布局方法
        void setElementLayout() {
            // 设置布局管理部件
            auto layout(new QGridLayout(this));
            layout->setContentsMargins(20, 10, 20, 0);
            layout->setSpacing(10);
            this->setMinimumHeight(100); // 指定整个子项的最小宽度
            this->setLayout(layout);

            if (isLeft_) {
                layout->addWidget(userBtn_, 0, 0, 2, 1, Qt::AlignTop | Qt::AlignLeft);
                layout->addWidget(nameLabel_, 0, 1);
                textMessageBubble_->setLeft(true);
                layout->addWidget(textMessageBubble_, 1, 1);
            } else { // isLeft_ != true
                layout->addWidget(userBtn_, 0, 1, 2, 1, Qt::AlignTop | Qt::AlignRight);
                layout->addWidget(nameLabel_, 0, 0, Qt::AlignRight);
                textMessageBubble_->setLeft(false);
                layout->addWidget(textMessageBubble_, 1, 0);
            }

            // TODO: 加上用户的个性化气泡
        }

        // 设置信号槽
        void setElementSignalSlot(const model::MessageModel& messageModel) {
            connect(userBtn_, &QPushButton::clicked, this, [=](){
                if(isLeft_) {
                    otherInfoWidget_ = new subassembly::OtherInfoWidget(messageModel.getMessageSenderUser(), this);
                    otherInfoWidget_->show();
                }
                else { // !isLeft_
                    selfInfoWidget_ = new subassembly::SelfInfoWidget(messageModel.getMessageSenderUser());
                    selfInfoWidget_->show();
                }
            });
        }
    };
} // namespace chat_system::subassembly end
// <<< class SessionFriendItem end <<<

// >>> class MessageShowArea begin: 滚动区域类 >>>

namespace chat_system::subassembly {
    class MessageShowArea : public QScrollArea {
    Q_OBJECT

    private:
        QWidget *container_; // 普通区域

    public:
        // 构造方法
        explicit MessageShowArea(QWidget *parent = nullptr)
                : QScrollArea(parent)
                , container_(new QWidget(this)) {
            this->setElement(); // 设置组件
            this->setElementStyle(); // 设置组件样式
            this->setElementLayout(); // 设置组件布局
            this->setElementSignalSlot(); // 设置信号槽
        }

        // 析构方法
        ~MessageShowArea() override = default;

        // 尾插子项
        void addTailTextMessageBubble(const bool &isLeft, const model::MessageModel &messageModel) {
            auto messageItem = new MessageItem(isLeft, messageModel);
            auto layout = dynamic_cast<QVBoxLayout*>(container_->layout());
            layout->addWidget(messageItem);
            this->verticalScrollBar()->setValue(this->verticalScrollBar()->maximum()); // 滚动条拉到最底下 TODO: 解决无法拉到最底下的问题
        }

        // 头插子项
        void addFrontTextMessageBubble(const bool &isLeft, const model::MessageModel &messageModel) {
            auto messageItem = new MessageItem(isLeft, messageModel);
            auto layout = dynamic_cast<QVBoxLayout *>(container_->layout());
            layout->insertWidget(0, messageItem);
        }

        // 清空子项
        void cleanAllTextMessageBubble() {
            auto layout = dynamic_cast<QVBoxLayout *>(container_->layout());
            for (int i = layout->count(); i >= 0; --i) {
                auto item = layout->takeAt(i);
                if (item != nullptr && item->widget() != nullptr) {
                    delete item->widget();
                }
            }
        }

    private:
        // 设置组件方法
        void setElement() {
            // 设置滚动区域和滚动条
            this->setWidgetResizable(true); // NOTE: 设置 Widget 可调整大小后才可以开启滚动效果
            this->verticalScrollBar()->setSingleStep(8); // 设置垂直滚动条的滚动步长为 8 像素
            this->setWidget(container_); // TODO: 这里应该就会导致 OriginalContainer_ 变成 SessionFriendArea 对象
        }

        // 设置组件样式方法
        void setElementStyle() {
            this->setStyleSheet("QScrollArea { border: none; }");
            this->verticalScrollBar()->setStyleSheet(
                    "QScrollBar:vertical {"
                    "width: 5px;"
                    "background-color: transparent;"
                    "}"
                    "QScrollBar::handle:vertical {"
                    "background: rgb(46, 46, 46);"
                    "}"
                    "QScrollBar::add-page:vertical, QScrollBar::sub-page:vertical {"
                    "background: transparent;"
                    "}"
            );
            this->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal { height: 0px }"); // 选择垂直方向滚动条样式进行设置, 禁止显示垂直方向的滚动条
            // 让滚动区域包含一个可变长的 QWidget 组件
            container_->setStyleSheet("QWidget { border: 1px solid rgb(10, 11, 11); border-top: none; border-bottom: none; }");
        }

        // 设置组件布局方法
        void setElementLayout() {
            // 给 Widget 组件添加布局
            auto layout_ = new QVBoxLayout();
            layout_->setContentsMargins(0, 0, 0, 0);
            layout_->setSpacing(0);
            layout_->setAlignment(Qt::AlignTop);
            container_->setLayout(layout_);
        }

        // 设置信号槽
        void setElementSignalSlot() {

        }
    };
} // namespace chat_system end
// <<< class MessageShowArea end <<<

#endif //FRONTEND_MESSAGESHOWAREA_HPP
